unit comboboxhelper;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Controls, StdCtrls, fpjson, database, namehelper;

{ This function uppercases the first letter of the combobox text }
function PreprocessComboboxValue(S: String): String;

{ The functions below only fill the list if it's non-empty. This behaviour
is used in TraitSelector. }
procedure FillDbArrayComboBox(List: TComboBox; Arr: TJSONArray; AdditionalFirstItem: String = '');
procedure FillSystemArrayComboBox(List: TComboBox; Db: TDatabase; ArrayName: String; StartFrom: Integer = 1);
procedure FillStateComboBox(List: TComboBox; Db: TDatabase; HasNormalAttackState: Boolean = False);
procedure FillSkillTypeComboBox(List: TComboBox; Db: TDatabase);
procedure FillWeaponTypeComboBox(List: TComboBox; Db: TDatabase);
procedure FillArmourTypeComboBox(List: TComboBox; Db: TDatabase);
procedure FillArmourEquipTypeComboBox(List: TComboBox; Db: TDatabase);
procedure FillEquipTypeComboBox(List: TComboBox; Db: TDatabase);
procedure FillSkillComboBox(List: TComboBox; Db: TDatabase);
procedure FillElementComboBox(ElementList: TComboBox; Db: TDatabase);
procedure FillParameterComboBox(List: TComboBox; Db: TDatabase);
procedure FillExParameterComboBox(List: TComboBox);
procedure FillSpParameterComboBox(List: TComboBox);
procedure FillSpecialFlagComboBox(List: TComboBox);
procedure FillKnockoutEffectComboBox(List: TComboBox);
procedure FillPartyFlagComboBox(List: TComboBox);
procedure FillCommonEventComboBox(List: TComboBox; Db: TDatabase);
procedure FillScopeComboBox(List: TComboBox);
procedure FillOccasionComboBox(List: TComboBox);
procedure FillHitTypeComboBox(List: TComboBox);
procedure FillDamageTypeComboBox(List: TComboBox);
procedure FillStateRestrictionComboBox(List: TComboBox);
procedure FillStateSvMotionComboBox(List: TComboBox);
procedure FillStateSvOverlayComboBox(List: TComboBox);
procedure FillStateAutoRemovalTimingComboBox(List: TComboBox);
procedure FillTilesetModeComboBox(List: TComboBox);
procedure FillCEvTriggerComboBox(List: TComboBox);

procedure FillMessageBgTypeCombobox(List: TComboBox);
procedure FillMessagePosCombobox(List: TComboBox);
procedure FillChoicePosCombobox(List: TComboBox);
procedure FillItemTypeCombobox(List: TComboBox);
procedure FillUserSelfSwitchNameCombobox(List: TComboBox);
procedure FillNamesComboBox(List: TComboBox; NameFn: TGetNameFn;
  MinValue: Integer; MaxValue: Integer); overload;
procedure FillNamesComboBox(List: TComboBox; Db: TDatabase;
  NameFn: TGetNameWithDbFn; MinValue: Integer; MaxValue: Integer); overload;
procedure FillMapCharacterComboBox(List: TComboBox; AMap: TJSONObject);



resourcestring
  NormalAttackState = 'Normal attack state';

implementation

uses
  constants, LazUTF8;

function PreprocessComboboxValue(S: String): String;
var
  InitialLetter, Rest: String;
begin
  InitialLetter := UTF8Copy(s, 1, 1);
  Rest := Copy(s, Length(InitialLetter)+1, MaxInt);
  PreprocessComboboxValue := UTF8Uppercase(InitialLetter) + Rest
end;

procedure FillDbArrayComboBox(List: TComboBox; Arr: TJSONArray;
  AdditionalFirstItem: String = '');
var
  I: Integer;
begin
  if List.Items.Count = 0 then begin
    List.Items.BeginUpdate;
    List.Clear;
    if AdditionalFirstItem <> '' then
      List.Items.Add(AdditionalFirstItem);
    for I := 1 to Arr.Count -1 do begin
      List.Items.Add(TDatabase.FormatObjName(Arr.Objects[I]));
    end;
    List.Items.EndUpdate;
    List.ItemIndex := 0;
  end;
end;

procedure FillSystemArrayComboBox(List: TComboBox; Db: TDatabase; ArrayName: String; StartFrom: Integer = 1);
var
  Items: TJSONArray;
  I: Integer;
begin
  if (List.Items.Count = 0) and (Db.System.Find(ArrayName, Items)) then begin
    List.Items.BeginUpdate;
    List.Clear;
    for I := StartFrom to Items.Count -1 do begin
      List.Items.Add('#' + IntToStr(I) + ' ' + Items.Strings[I]);
    end;
    List.Items.EndUpdate;
    List.ItemIndex := 0;
  end;
end;

procedure FillStateComboBox(List: TComboBox; Db: TDatabase; HasNormalAttackState: Boolean = False);
begin
  if HasNormalAttackState then
    FillDbArrayComboBox(List, Db.States, NormalAttackState)
  else
    FillDbArrayComboBox(List, Db.States);
end;

procedure FillSkillTypeComboBox(List: TComboBox; Db: TDatabase);
begin
  FillSystemArrayComboBox(List, Db, 'skillTypes');
end;

procedure FillWeaponTypeComboBox(List: TComboBox; Db: TDatabase);
begin
  FillSystemArrayComboBox(List, Db, 'weaponTypes');
end;

procedure FillArmourTypeComboBox(List: TComboBox; Db: TDatabase);
begin
  FillSystemArrayComboBox(List, Db, 'armorTypes');
end;

procedure FillArmourEquipTypeComboBox(List: TComboBox; Db: TDatabase);
begin
  FillSystemArrayComboBox(List, Db, 'equipTypes', 2)
end;

procedure FillEquipTypeComboBox(List: TComboBox; Db: TDatabase);
begin
  FillSystemArrayComboBox(List, Db, 'equipTypes');
end;

procedure FillSkillComboBox(List: TComboBox; Db: TDatabase);
begin
  FillDbArrayComboBox(List, Db.Skills);
end;

procedure FillElementComboBox(ElementList: TComboBox; Db: TDatabase);
begin
  FillSystemArrayComboBox(ElementList, Db, 'elements');
end;

procedure FillParameterComboBox(List: TComboBox; Db: TDatabase);
var
  I: Integer;
  Terms: TJSONObject;
  ParamNames: TJSONArray;
begin
  if (List.Items.Count = 0) and Db.System.Find('terms', Terms) then begin
    if Terms.Find('params', ParamNames) then begin
      List.Items.BeginUpdate;
      for I := 0 to 7 do begin
        List.Items.Add(ParamNames.Strings[I]);
      end;
      List.Items.EndUpdate;
      List.ItemIndex := 0
    end;
  end;
end;

procedure FillExParameterComboBox(List: TComboBox);
var
  I: Integer;
begin
  if List.Items.Count = 0 then begin
    List.Items.BeginUpdate;
    for I := Low(ExParamNames) to High(ExParamNames) do begin
      List.Items.Add(ExParamNames[I]);
    end;
    List.Items.EndUpdate;
    List.ItemIndex := 0
  end;
end;

procedure FillSpParameterComboBox(List: TComboBox);
var
  I: Integer;
begin
  if List.Items.Count = 0 then begin
    List.Items.BeginUpdate;
    for I := Low(SpParamNames) to High(SpParamNames) do begin
      List.Items.Add(SpParamNames[I]);
    end;
    List.Items.EndUpdate;
    List.ItemIndex := 0
  end;
end;

procedure FillSpecialFlagComboBox(List: TComboBox);
var
  I: Integer;
begin
  if List.Items.Count = 0 then begin
    List.Items.BeginUpdate;
    for I := Low(SpecialFlagNames) to High(SpecialFlagNames) do begin
      List.Items.Add(SpecialFlagNames[I]);
    end;
    List.Items.EndUpdate;
    List.ItemIndex := 0
  end;
end;

procedure FillKnockoutEffectComboBox(List: TComboBox);
var
  I: Integer;
begin
  if List.Items.Count = 0 then begin
    List.Items.BeginUpdate;
    for I := Low(KnockoutEffectFlagNames) to High(KnockoutEffectFlagNames) do begin
      List.Items.Add(KnockoutEffectFlagNames[I]);
    end;
    List.Items.EndUpdate;
    List.ItemIndex := 0
  end;
end;

procedure FillPartyFlagComboBox(List: TComboBox);
var
  I: Integer;
begin
  if List.Items.Count = 0 then begin
    List.Items.BeginUpdate;
    for I := Low(PartyFlagFlagNames) to High(PartyFlagFlagNames) do begin
      List.Items.Add(PartyFlagFlagNames[I]);
    end;
    List.Items.EndUpdate;
    List.ItemIndex := 0
  end;
end;

procedure FillCommonEventComboBox(List: TComboBox; Db: TDatabase);
begin
  FillDbArrayComboBox(List, Db.CommonEvents);
end;

procedure FillScopeComboBox(List: TComboBox);
begin
  with List.Items do begin
    BeginUpdate;
    Clear;

    Add(rsScopeNone);
    Add(rsScopeSingleEnemy);
    Add(rsScopeAllEnemies);
    Add(rsScope1RandomEnemy);
    Add(rsScope2RandomEnemies);
    Add(rsScope3RandomEnemies);
    Add(rsScope4RandomEnemies);
    Add(rsScope5RandomEnemies);
    Add(rsScopeAllAllies);
    Add(rsScope1UnconsciousAlly);
    Add(rsScopeAllUnconsciousAllies);
    Add(rsScopeUser);
    EndUpdate;
  end;
end;

procedure FillOccasionComboBox(List: TComboBox);
begin
  with List.Items do begin
    BeginUpdate;
    Clear;

    Add(rsOccasionAlways);
    Add(rsOccasionBattle);
    Add(rsOccasionMap);
    Add(rsOccasionNone);
    EndUpdate;
  end;
end;

procedure FillHitTypeComboBox(List: TComboBox);
begin
  with List.Items do begin
    BeginUpdate;
    Clear;

    Add(rsHitTypeCertain);
    Add(rsHitTypePhysical);
    Add(rsHitTypeMagical);
    EndUpdate;
  end;
end;

procedure FillDamageTypeComboBox(List: TComboBox);
begin
  with List.Items do begin
    BeginUpdate;
    Clear;

    Add(rsDamageTypeNone);
    Add(rsDamageTypeDamageHp);
    Add(rsDamageTypeDamageMp);
    Add(rsDamageTypeHealHp);
    Add(rsDamageTypeHealMp);
    Add(rsDamageTypeStealHp);
    Add(rsDamageTypeStealMp);
    EndUpdate;
  end;
end;

procedure FillNames(List: TComboBox; NameFn: TGetNameFn; MinValue: Integer;
  MaxValue: Integer);
var
  I: Integer;
begin
  with List.Items do begin
    BeginUpdate;
    Clear;

    for I := MinValue to MaxValue do begin
      Add(PreprocessComboboxValue(NameFn(I)));
    end;

    EndUpdate;
  end;
end;

procedure FillStateRestrictionComboBox(List: TComboBox);
begin
  FillNames(List, @GetStateRestrictionName, 0, 4);
end;

procedure FillStateSvMotionComboBox(List: TComboBox);
begin
  FillNames(List, @GetStateSvMotionName, 0, 3);
end;

procedure FillStateSvOverlayComboBox(List: TComboBox);
begin
  FillNames(List, @GetStateSvOverlayName, 0, 10);
end;

procedure FillStateAutoRemovalTimingComboBox(List: TComboBox);
begin
  FillNames(List, @GetStateAutoRemovalTimingName, 0, 2);
end;

procedure FillTilesetModeComboBox(List: TComboBox);
begin
  FillNames(List, @GetTilesetMode, 0, 1);
end;

procedure FillCEvTriggerComboBox(List: TComboBox);
begin
  FillNames(List, @GetCEvTriggerName, 0, 2);
end;

procedure FillMessageBgTypeCombobox(List: TComboBox);
begin
  FillNames(List, @GetMessageBgTypeName, 0, 2);
end;

procedure FillMessagePosCombobox(List: TComboBox);
begin
  FillNames(List, @GetMessagePosName, 0, 2);
end;

procedure FillChoicePosCombobox(List: TComboBox);
begin
  FillNames(List, @GetChoicePosName, 0, 2);
end;

procedure FillItemTypeCombobox(List: TComboBox);
begin
  FillNames(List, @GetItemTypeName, 0, 3);
end;

procedure FillUserSelfSwitchNameCombobox(List: TComboBox);
begin
  FillNames(List, @GetUserSelfSwitchName, 0, 3);
end;

procedure FillNamesComboBox(List: TComboBox; NameFn: TGetNameFn;
  MinValue: Integer; MaxValue: Integer);
begin
  FillNames(List, NameFn, MinValue, MaxValue);
end;

procedure FillNamesComboBox(List: TComboBox; Db: TDatabase;
  NameFn: TGetNameWithDbFn; MinValue: Integer; MaxValue: Integer);
var
  I: Integer;
begin
  with List.Items do begin
    BeginUpdate;
    Clear;

    for I := MinValue to MaxValue do begin
      Add(PreprocessComboboxValue(NameFn(Db, I)));
    end;

    EndUpdate;
  end;
end;

procedure FillMapCharacterComboBox(List: TComboBox; AMap: TJSONObject);
var
  I: Integer;
  Events: TJSONArray;
begin
  with List.Items do begin
    BeginUpdate;
    Clear;

    Add(FormatChar(-1));
    Add(FormatChar(0));

    if AMap <> nil then begin
      Events := AMap.Arrays['events'];
      if Events.Count > 1 then
        for I := 1 to Events.Count - 1 do
          Add(FormatChar(I));
    end;

    EndUpdate;
  end;
end;



end.
